﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ServiceStack.Redis;
using CYTS.Aoyou.Framework.Log;

namespace CYTS.Aoyou.Framework.Cache
{
    /// <summary>
    /// Redis操作帮助类
    /// </summary>
    public class RedisHelper
    {
        private static Dictionary<string, PooledRedisClientManager> dicRedisClientManager = new Dictionary<string, PooledRedisClientManager>();
        private static object lockObj = new object();

        private PooledRedisClientManager manager = null;
        private string region = "Default";

        public RedisHelper(string host, int port, int db, string password, string region)
        {
            string key = password + "@" + host + ":" + port + "#" + db;
            if (!dicRedisClientManager.TryGetValue(key, out manager))
            {
                lock (lockObj)
                {
                    if (!dicRedisClientManager.TryGetValue(key, out manager))
                    {
                        manager = new PooledRedisClientManager(new string[] { password + "@" + host + ":" + port }, new string[] { password + "@" + host + ":" + port }, new RedisClientManagerConfig
                        {
                            MaxWritePoolSize = 10,//“写”链接池链接数
                            MaxReadPoolSize = 10,//“读”链接池链接数
                            AutoStart = true,
                        }, db, null, 10);
                        dicRedisClientManager[key] = manager;
                    }
                }
            }

            this.region = region;
        }

        /// <summary>
        /// 清除内存中的所有ClientManager
        /// </summary>
        public static void RemoveAllClientManagerInMemory()
        {
            lock (lockObj)
            {
                dicRedisClientManager.Clear();
            }
        }

        /// <summary>
        /// 获取内存中的所有ClientManager
        /// </summary>
        /// <returns></returns>
        public static IList<PooledRedisClientManager> GetAllClientManagerListInMemory()
        {
            return dicRedisClientManager.Values.ToList();
        }

        public void Add<T>(string key, T value, TimeSpan expiration)
        {
            string realKey = region + "#" + key;
            try
            {
                using (var client = manager.GetClient())
                {
                    client.Set(realKey, value, expiration);
                }
            }
            catch (Exception ex)
            {
                string msg = "新增缓存数据失败";
                //Logger.LogError(msg, ex);
                throw new Exception(msg, ex);
            }
        }

        public void Add<T>(string key, T value)
        {
            string realKey = region + "#" + key;
            try
            {
                using (var client = manager.GetClient())
                {
                    client.Set(realKey, value);
                }
            }
            catch (Exception ex)
            {
                string msg = "新增缓存数据失败";
                //Logger.LogError(msg, ex);
                throw new Exception(msg, ex);
            }
        }

        public T Get<T>(string key)
        {
            string realKey = region + "#" + key;
            try
            {
                using (var client = manager.GetClient())
                {
                    return client.Get<T>(realKey);
                }
            }
            catch (Exception ex)
            {
                string msg = "获取缓存数据失败";
                //Logger.LogError(msg, ex);
                throw new Exception(msg, ex);
            }
        }

        public void Remove(string key)
        {
            string realKey = region + "#" + key;
            try
            {
                using (var client = manager.GetClient())
                {
                    client.Remove(realKey);
                }
            }
            catch (Exception ex)
            {
                string msg = "删除缓存数据失败";
                //Logger.LogError(msg, ex);
                throw new Exception(msg, ex);
            }
        }

        public bool ContainsKey<T>(string key)
        {
            string realKey = region + "#" + key;
            try
            {
                using (var client = manager.GetClient())
                {
                    return client.ContainsKey(realKey);
                }
            }
            catch (Exception ex)
            {
                string msg = "判断缓存数据是否存在时失败";
                //Logger.LogError(msg, ex);
                throw new Exception(msg, ex);
            }
        }

        public void Flush()
        {
            try
            {
                using (var client = manager.GetClient())
                {
                    client.FlushAll();
                }
            }
            catch (Exception ex)
            {
                string msg = "Flush缓存数据时失败";
                //Logger.LogError(msg, ex);
                throw new Exception(msg, ex);
            }
        }



        public List<string> GetAllKeys(string pattern = "*")
        {
            List<string> allKeys = new List<string>();
            string realPattern = region + "#" + pattern;
            try
            {
                using (var client = manager.GetClient())
                {
                    var redisClient = (RedisClient)client;
                    var tempKeyList = redisClient.SearchKeys(realPattern);
                    foreach(var tempKey in tempKeyList)
                    {
                        var array = tempKey.Split('#');
                        if(array.Length > 1)
                        {
                            allKeys.Add(array[1]);
                        }
                    }
                    return allKeys;
                }
            }
            catch (Exception ex)
            {
                string msg = "获取缓存数据失败";
                //Logger.LogError(msg, ex);
                throw new Exception(msg, ex);
            }
        }


        public void RemoveAll(string pattern = "*")
        {
            List<string> allKeys = new List<string>();
            string realPattern = region + "#" + pattern;
            try
            {
                using (var client = manager.GetClient())
                {
                    var redisClient = (RedisClient)client;
                    var keyList = redisClient.SearchKeys(realPattern);
                    if (keyList != null && keyList.Count > 0)
                    {
                        redisClient.RemoveAll(keyList);
                    }
                }
            }
            catch (Exception ex)
            {
                string msg = "删除缓存数据失败";
                //Logger.LogError(msg, ex);
                throw new Exception(msg, ex);
            }
        }
    }
}
